package tests;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Hashtable;

import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import tests.mocks.AerolineaLanchitaMock;
import tests.mocks.TodasLasAerolineasMock;
import tests.mocks.VueloDirectoMock;
import usuario.TipoUsuarioVip;
import utils.fecha.FormateadorSimple;
import vuelo.Vuelo;
import vuelo.VueloDirecto;
import aerolinea.Aerolinea;
import aerolinea.LanchitaAdapter;
import asiento.Asiento;
import busqueda.Busqueda;
import busqueda.BusquedaConEscala;
import formatos.LanchitaFormater;


public class VueloConEscalasTest {
	
	TodasLasAerolineasMock aerolineasController;
	LanchitaAdapter lanchita;
	Busqueda busquedaConEscalas;
	Busqueda busquedaSinEscalas;
	FormateadorSimple formateadorSimple;
	
	Collection<Aerolinea> aerolineas;
	
	@Before
	public void setUp() throws Exception {
		lanchita = new LanchitaAdapter();
		lanchita.setInstance(new AerolineaLanchitaMock(this.mockLanchitaData()));
		
		aerolineas = new ArrayList<Aerolinea>();
		aerolineas.add(lanchita);
		
		aerolineasController = TodasLasAerolineasMock.getInstance();
		aerolineasController.setAerolineas(aerolineas);
		aerolineasController.setVuelosPorCodigoDeVuelo(this.mockTodasLasAerolineasData());
		
		formateadorSimple = new LanchitaFormater();
		Date fechaBusqueda = formateadorSimple.convertir("17/08/2012-22:10");
		
		busquedaConEscalas = new BusquedaConEscala("EZE", "USA", fechaBusqueda.toString());
		busquedaConEscalas.setTipoUsuario(new TipoUsuarioVip());
		
		busquedaSinEscalas = new Busqueda("EZE", "USA", fechaBusqueda.toString());
		busquedaSinEscalas.setTipoUsuario(new TipoUsuarioVip());
		
	}
	
	@Test
	public void testVueloConEscalaTiempo() throws ParseException {
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		BigDecimal tiempoTotal = new BigDecimal(0);
		for (Vuelo vuelo : vuelos) {
			tiempoTotal = tiempoTotal.add(vuelo.dameTiempoDeVuelo());
		}
		long tiempoVueloDirecto = 12; 
		long tiempoPrimerVuelo = 66;
		long tiempoSegundoVuelo = 46;
		long tiempoSuma = tiempoVueloDirecto + tiempoPrimerVuelo + tiempoSegundoVuelo;
		Assert.assertTrue(tiempoTotal.longValue()==(new BigDecimal(tiempoSuma).longValue()));
	}
	@Test
	public void testVueloConEscalaPrecio() throws ParseException {
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		BigDecimal precioTotal = new BigDecimal(0);
		for (Vuelo vuelo : vuelos) {
			precioTotal=precioTotal.add(vuelo.damePrecioMaximo());
		}
		double precioUnitario = 256.50;
		double impuesto = precioUnitario * 0.15;
		double precioPorVuelo = precioUnitario + impuesto; 
		long cantidadVuelos = 1 + 2 * 2; //uno directo,dos de dos escalas
		Assert.assertTrue(precioTotal.longValue()==(new BigDecimal(precioPorVuelo*cantidadVuelos).longValue()));
	}
	@Test
	public void testVueloConEscalaPopularidad() throws ParseException {
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		BigDecimal popularidadTotal = new BigDecimal(0);
		for (Vuelo vuelo : vuelos) {
			popularidadTotal = popularidadTotal.add(vuelo.damePopularidad());
		}
		Assert.assertTrue(popularidadTotal.longValueExact()== 1);
	}
	@Test
	public void testVueloConEscalasValido() throws ParseException {
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		Assert.assertTrue(vuelos.size()==3);
	}
	@Test
	public void testVueloSinEscalasValida() throws ParseException {
		busquedaConEscalas.setDestino("ESPA�A");
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		Assert.assertTrue(vuelos.size()==0);
	}
	@Test
	public void testVueloConSegundaEscalasNoValidoPorTiempo() throws ParseException {
		busquedaConEscalas.setOrigen("ARG");
		busquedaConEscalas.setDestino("BRA");
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaConEscalas);
		Assert.assertTrue(vuelos.size()==1);
	}
	
	@Test
	public void testVueloConEscalaYBusquedaSinEscala() throws ParseException {
		Collection<Vuelo> vuelos=aerolineasController.buscarVuelos(busquedaSinEscalas);
		Assert.assertTrue(vuelos.size()==1);
	}
	
	@After
	public void tearDown() throws Exception {
			lanchita.setInstance(null);
	}
	
	public String[][] mockLanchitaData(){
		return new String[][] {
				{ "01202022220203-3", "159.90", "PRIMERACLASE", "VENTANA", "DISPONIBLE", "", "14:00","22:25","ARG","URU","16/08/2012","17/08/2012" },
				{ "01202022256566-3", "282.19", "TURISTA", "CENTRO", "DISPONIBLE", "", "23:25","22:00","URU","BRA","17/08/2012","18/08/2012" },
				{ "01202022220204-3", "159.90", "PRIMERACLASE", "VENTANA", "DISPONIBLE", "", "14:00","22:25","ARG","PAR","16/08/2012","17/08/2012" },
				{ "01202022256565-3", "282.19", "TURISTA", "CENTRO", "DISPONIBLE", "", "23:55","22:00","PAR","URU","17/08/2012","18/08/2012" },
				
				{ "01202022220202-3", "256.50", "PRIMERACLASE", "VENTANA", "DISPONIBLE", "", "14:00","02:00","EZE","USA","16/08/2012","17/08/2012" },
				
				{ "01202022267867-7", "256.50", "EJECUTIVA", "PASILLO", "DISPONIBLE", "", "05:00","21:00","EZE","PER","16/08/2012","17/08/2012" },
				{ "01202022220008-3", "256.50", "TURISTA", "VENTANA", "DISPONIBLE", "", "22:00","23:00","PER","USA","17/08/2012","18/08/2012" },
				{ "01202022256565-3", "256.50", "TURISTA", "CENTRO", "DISPONIBLE", "", "20:00","22:00","EZE","AEO","16/08/2012","17/08/2012" },
				{ "01202022323423-5", "256.50", "TURISTA", "CENTRO", "DISPONIBLE", "", "23:00","18:00","AEO","USA","17/08/2012","18/08/2012"} 
//				{ "01202022220298-2", "528.81", "PRIMERACLASE", "VENTANA", "DISPONIBLE", "", "07:00","08:00","AEO","USH","16/08/2012","17/08/2012"} });
		};
	}

	public Hashtable<String, Vuelo> mockTodasLasAerolineasData(){
		Hashtable<String, Vuelo> vuelosMock = new Hashtable<String, Vuelo>();
		Asiento unAsiento = new Asiento();
		unAsiento.setFechaSalida(new Date(0));
		unAsiento.setFechaLlegada(new Date(1000));
		VueloDirecto unVueloDirecto = new VueloDirecto("012",unAsiento);
		unVueloDirecto.addAsiento(unAsiento);
		
		VueloDirectoMock vueloMock = new VueloDirectoMock(unVueloDirecto);
		
//		Collection<Asiento> asientosMock = new ArrayList<Asiento>();
//		asientosMock.add(new Asiento());
//		
//		vueloMock.setAsientos(asientosMock);
		
		vuelosMock.put("01202022220202", vueloMock);
		return vuelosMock;
	}
}
